﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace cs2335lab5
{
    namespace Client
    {
        /// <summary>
        /// Interaction logic for UserDetail.xaml
        /// </summary>
        public partial class UserDetail : Window
        {
            /// <summary>
            /// The user we're acting on
            /// </summary>
            public Data.User Current { get; protected set; }

            /// <summary>
            /// Shortcut to the logged-in user
            /// </summary>
            public Data.User User
            {
                get
                {
                    return App.Instance().User;
                }
            }

            /// <summary>
            /// GUI setup method
            /// </summary>
            public UserDetail()
            {
                InitializeComponent();
            }

            /// <summary>
            /// Loads a user from the server
            /// </summary>
            /// <param name="id"></param>
            public void Load(string id)
            {
                // if we're passed null, just make a new user
                if (id == null)
                {
                    Current = new Data.User();
                }
                else
                {
                    // otherwise ask the server about this issue
                    Current = App.Instance().Proxy.GetUser(id);

                    // if we're returned null, make a new issue
                    // TODO: may want to notify the user that the local issue is invalid
                    if (Current == null)
                    {
                        Current = new Data.User();
                    }
                }

                // implement access rights
                if (Current.ID == null | Current.ID.Equals("") 
                    || User.Access == Data.User.Privileges.Admin)
                {
                    // enable all of the fields except for ID, creator, and creation date
                    // issue doesn't exist or user is an admin
                    idTextBox.IsEnabled = 
                        (Current.ID == null || Current.ID.Equals("")); // Current.ID
                    nameTextBox.IsEnabled = true;                   // Current.Name;
                    passwordBox.IsEnabled = true;                   // Current.AssignedTo;
                    accessBox.IsEnabled = 
                        User.Access.Equals(Data.User.Privileges.Admin); // Current.Access
                    emailTextBox.IsEnabled = true;                  // Current.Email
                    loggedInTextBox.IsEnabled = false;              // Current.isLoggedIn
                }
                else if (Current.ID.Equals(User.ID))
                {
                    // normal user is editing their own entry
                    idTextBox.IsEnabled = false;                    // Current.ID
                    nameTextBox.IsEnabled = true;                   // Current.Name;
                    passwordBox.IsEnabled = true;                   // Current.AssignedTo;
                    accessBox.IsEnabled = false;                // Current.Access
                    emailTextBox.IsEnabled = true;                  // Current.Email
                    loggedInTextBox.IsEnabled = false;              // Current.isLoggedIn
                }
                else
                {
                    // normal user is viewing another user's entry
                    idTextBox.IsEnabled = false;                    // Current.ID
                    nameTextBox.IsEnabled = false;                  // Current.Name;
                    passwordBox.IsEnabled = false;                  // Current.AssignedTo;
                    accessBox.IsEnabled = false;                // Current.Access
                    emailTextBox.IsEnabled = false;                 // Current.Email
                    loggedInTextBox.IsEnabled = false;              // Current.isLoggedIn
                }

                // until we get data binding working, we have to manually 
                // put information into the UI elements
                idTextBox.Text = (Current.ID != null) ? Current.ID : "";
                nameTextBox.Text = (Current.Name != null) ? Current.Name : "";
                passwordBox.Password = (Current.Password != null) ? Current.Password : "";
                accessBox.Text = (Current.Access == null) ? "" :
                    Enum.GetName(typeof(Data.User.Privileges), Current.Access);
                emailTextBox.Text = (Current.Email != null) ? Current.Email : "";
                loggedInTextBox.Text = (Current.isLoggedIn) ? "Yes" : "No";
            }

            private void ParseAndSaveData()
            {
                // TODO: make sure all of the fields are filled out
                // TODO: make date due into a date picker (or possibly a date/time picker
                // TODO: make assigned to a dropdown box with a list of users
                // TODO: admins can select from all users, normals can only select themselves
                // TODO: make status a dropdown box of statuses

                // read in the fields and assign them to variables until we get data binding working
                if (Current == null)
                {
                    Current = new Data.User();
                }
                /*
                idTextBox.Text = (Current.ID != null) ? Current.ID : "";
                nameTextBox.Text = (Current.Name != null) ? Current.Name : "";
                passwordBox.Password = (Curent.Password != null) ? Current.Password : "";
                accessTextBox.Text = (Current.Access == null) ? "" :
                    Enum.GetName(typeof(Data.User.Privileges), Current.Access);
                emailTextBox.Text = (Current.Email != null) ? Current.Email : "";
                loggedInTextBox.Text = (Current.isLoggedIn) ? "Yes" : "No";*/

                // assign fields
                Current.ID = idTextBox.Text;
                Current.Name = nameTextBox.Text;
                Current.Password = passwordBox.Password;
                try
                {
                    Current.Access = (Data.User.Privileges)Enum.Parse(typeof(Data.User.Privileges), accessBox.Text);
                }
                catch (ArgumentException)
                {
                    Current.Access = Data.User.Privileges.Normal;
                }
                Current.Email = emailTextBox.Text;
                // just ignore the logged in var here, it could have changed

                // take the current state of the form and update the issue on the server
                if (Current.ID == null)
                {
                    Current = App.Instance().Proxy.AddUser(User, Current);
                }
                else
                {
                    Current = App.Instance().Proxy.UpdateUser(User, Current);
                }
            }

            /// <summary>
            /// Save the data but don't exit
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Apply_Click(object sender, RoutedEventArgs e)
            {
                // send the data to the server
                ParseAndSaveData();

                // notify the ClientForm it needs to update
                App.Instance().UpdateClient();

                // update the window
                if (Current != null && Current.ID != null)
                {
                    Load(Current.ID);
                }
            }

            /// <summary>
            /// Save button event handler
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OK_Click(object sender, RoutedEventArgs e)
            {
                // send the data to the server
                ParseAndSaveData();

                // notify the ClientForm it needs to update
                App.Instance().UpdateClient();

                // hide the window
                Cancel_Click(sender, e);
            }

            /// <summary>
            /// Cancel button event handler
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Cancel_Click(object sender, RoutedEventArgs e)
            {
                // clear the data in the form and hide it
                Current = new Data.User();
                this.Hide();
            }

            /// <summary>
            /// When the window is closed, just hide it
            /// code from http://balajiramesh.wordpress.com/2008/07/24/hide-a-window-instead-of-closing-it-in-wpf/
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                // Hide Window
                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                    (DispatcherOperationCallback)delegate(object o)
                    {
                        Hide();
                        return null;
                    }, null);

                // Do not close window
                e.Cancel = true;
            }

            /// <summary>
            /// Validate the username text box
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void idTextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                // if there is no name
                if (idTextBox == null || idTextBox.Text == null || idTextBox.Text.Equals(""))
                {
                    // then the user can't click OK or Apply
                    Apply.IsEnabled = false;
                    Apply.ToolTip = "Cannot save issue with a blank name.";
                    OK.IsEnabled = false;
                    OK.ToolTip = "Cannot save issue with a blank name.";

                    // highlight the box
                    idTextBox.Background = new SolidColorBrush(Colors.LightCoral);
                }
                else
                {
                    // otherwise they can be
                    Apply.IsEnabled = true;
                    Apply.ToolTip = "Save issue and keep dialog open";
                    OK.IsEnabled = true;
                    OK.ToolTip = "Save issue and close dialog";

                    // unhighlight the box
                    idTextBox.Background = new SolidColorBrush(Colors.White);
                }
            }
        }
    }
}